#!/usr/bin/env python

"""
/* radar_main.py - it's a radar UI game based on diversity-daemon 
 *
 * Copyright 2009 
 * Authored by Erin Yueh <erinyueh@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 */
"""

import ecore.evas
import ecore
import math
import edje

SCREEN_GEOMETRY = (480, 640)
THEME = "/usr/share/diversity-radar/diversity_radar.edj"

from radar import radar_target, radar_edbus, radar_map, radar_math

def button_cb(zoom_in, emission, source):

	speed = ee.data["speed"]
	if(source == 'speed-up'):
		rate_up_mouse_up_add_cb(ee.data["speed"])
	elif(source == 'speed-down'):
		rate_down_mouse_up_add_cb(ee.data["speed"])	

	radar = ee.data["radar"]
	target_list = ee.data["target_list"]
	if(source == 'zoom-in'):	
		zoom_in_mouse_up_add_cb(radar,radar.radius,target_list)
	elif(source == 'zoom-fit'):	
		zoom_fit_mouse_up_add_cb(radar,radar.radius,target_list)
	elif(source == 'zoom-out'):	
		zoom_out_mouse_up_add_cb(radar,radar.radius,target_list)

	return True

def rate_up_mouse_up_add_cb(speed):
	# speed up the scaning rate
	speed += 0.1
	ee.data["speed"] = speed
	print 'speed up to',speed
	return True
    
def rate_down_mouse_up_add_cb(speed):
	# speed down the scaning rate
	if(speed >= 0.2):
		speed -= 0.1
	ee.data["speed"] = speed	
	print 'speed down to',speed
	return True

def zoom_in_mouse_up_add_cb(radar,radius,target_list):
	# increase the viewport radius 
	radius += 10.0
	if(radius>=90.0):
		radius = 90.0
	radar.setRadius(radius)
	print 'set radius up to ',radius
	# refresh all target in map
	refresh_target_list_inMap(radar,target_list)
	return True

def zoom_out_mouse_up_add_cb(radar,radius,target_list):
	# decrease the viewport radius 
	if(radius>=20.0):
		radius -= 10.0
	radar.setRadius(radius)
	print 'set radius down to ',radius
	# refresh all target in map
	refresh_target_list_inMap(radar,target_list)
	return True

def zoom_fit_mouse_up_add_cb(radar,radius,target_list):
	# reset the viewport radius to 50.0
	radius = 50.0
	print "radius", radius
	radar.setRadius(radius)
	print 'set radius to ',radius
	# refresh all target in map
	refresh_target_list_inMap(radar,target_list)
	return True
	
def refresh_target_list_inMap(radar,target_list):

	bg = ee.data['map']
	neome_x1, neome_y1 = radar.getNEOME()
	radius = radar.radius
	# check each target in list
	for name, target in target_list.iteritems():
		(x1,y1) = target.get_coordinate(name)
		# get target image object by path name
		obj = ee.data[name]
		w1, h1 = obj.image_size 
		(x2,y2) = radar_math.calObjectGeometryToCoord(x1,y1,bg.w,bg.h,neome_x1, neome_y1,radius)
		obj.geometry_set(int(x2),int(y2),int(w1),int(h1))
		# change tag description position
		text = obj.data["text"]
		text.pos_set(x2+5,y2+5)
		my_flash(obj)
        
	return True

def create_target(path):

    # heart image, tag name, tag description
    target_list = ee.data["target_list"]
    sobject = ee.data["radar"].getDiversityObject(path)
    # get object geometry info
    (lon,lat,w1,h1) = sobject.GeometryGet()
    center_x, center_y = (ee.data["map"].w/2,ee.data["map"].h/2)
    neome_lon,neome_lat = ee.data["radar"].getNEOME()
    radius = ee.data["radar"].radius

    # get the coordinate for UI (self,lon,lat,bg,x1,y1,r)
    (x2,y2) = radar_math.calObjectGeometryToCoord(lon,lat,ee.data["map"].w,ee.data["map"].h,neome_lon,neome_lat,radius)
    device_degree = radar_math.getObjectDegree(center_x,center_y,x2,y2)
    device_distance = radar_math.calObjectDistance(neome_lon,neome_lat,lon,lat)

    # add one target object to target_list dict, key is path name
    target_list[path] = radar_target.TARGET(path)
    target_list[path].set_coordinate(lon,lat)
    target_list[path].set_UI_coordinate(x2,y2)
    target_list[path].set_degree(device_degree)
    target_list[path].set_distance(device_distance)
    target_list[path].set_description(ee.data["radar"].getTagDescription(path))

    # create an image object
    heart = ee.data["bg"].part_object_get("heart")
    w1, h1 = heart.image_size
    heart.size = (w1, h1)
    heart.fill = (0, 0, w1, h1)
    heart.geometry_set(0,0,0,0)
    heart.data["flash_timer"] = None
    # save this image object to data[] by path name
    ee.data[path] = heart

    # create a Text object
    text = ee.data["bg"].part_object_get("flash_name")
    text.text_set(ee.data["radar"].getTagDescription(path))
    text.pos_set(x2+5,y2+5)
    heart.data["text"] = text
    text.show()
    return True

def ObjectAdded_cb(path):
	#print 'object added callback',path

	# retrieve diversity object by path
	sobject = ee.data["radar"].getDiversityObject(path)
	# we are only interested in tags
	if (sobject.GetType() != 2):
		return

	target_list = ee.data["target_list"]
	# add one object to target_list dictionary
	if(path not in target_list):
    	   create_target(path)
	return True
	
def ObjectRemoved_cb(path):
	
	print 'object removed callback',path
	# remove it from target_list 
	target_list = ee.data["target_list"]	
	if(path in target_list):
		del target_list[path]
	# remove the image/text object
	target = ee.data[path]
	target.data["text"].hide()
	target.hide()
	del ee.data[path]
	
	return True

def animate_line():
	
	line = ee.data["line"]
	bg = ee.data["map"]
	w, h = bg.size_get()
	(center_x, center_y) = (w/2,h/2)
	line.center = (center_x, center_y)
	
	line_degree = line.data["degree"] + (
		ee.data["speed"] * ( ecore.time_get() - line.data["last_time"]))
	line_degree %= (2*math.pi)
	line.data["last_time"] = ecore.time_get()
	line.data["degree"] = line_degree

	x = center_x + w* 0.5 * math.cos(line_degree-(math.pi*0.5))
	y =  center_y + w * 0.5 * math.sin(line_degree-(math.pi*0.5))
	line.xy_set (center_x, center_y, int(x), int(y))
	radar = ee.data["radar"]
	neome_x1, neome_y1 = radar.getNEOME()
	radius = radar.radius

	target_list = ee.data["target_list"]

    # check each target in list
	for name, target in target_list.iteritems():
		(x1,y1) = target.get_coordinate(name)
		# get target image object by path name
		obj = ee.data[name]
		w1, h1 = obj.image_size 
		(x2,y2) = radar_math.calObjectGeometryToCoord(x1,y1,bg.w,bg.h,neome_x1, neome_y1,radius)
		obj_degree = target.get_degree(name)
		
		if(math.fabs(obj_degree - line_degree) < 0.06): # close enough
			obj.geometry_set(int(x2),int(y2),int(w1),int(h1))
		    # change tag description position
			text = obj.data["text"]
			text.text_set(target.get_description(name))
			text.pos_set(x2+5,y2+5)
			# change flash text 
			flash_tag = ee.data["bg"].part_object_get("flash_tag")
			(lon,lat) = target.get_coordinate(name)
			desc = target.get_description(name)
			display_text = "longitude = " + str(lon) + " , latitude = " + str(lat) + " , name = " +  text.text_get()
			flash_tag.text_set(display_text)
			my_flash(obj)
	
	return True	

def my_flash(obj):
	
	if(obj.data["flash_timer"]):
		obj.color_set(255,255,255,255)
		return 
    
	obj.color_set(255,255,255,255)
	obj.show()
	text = obj.data["text"] 
	text.color_set(200,180,180,255)
	text.show()

	# run flash every 0.05 sec
	flash_timer = ecore.timer_add(0.05, flash,obj)
	obj.data["flash_timer"] = flash_timer
	obj.data["flag"] = 0
	return True
        
def flash(obj):

	(r,g,b,alpha) = obj.color_get()
	text = obj.data["text"] 
	if(obj.data["flag"] ==1): # fade in
	    alpha+= 10
	elif(obj.data["flag"] ==0): # fade out
		alpha-= 10
	if(alpha >= 255):
		obj.data["flag"] = 0
        elif(alpha <= 0):
                obj.hide()
                text.color_set(180,20,100,255)
                obj.data["flash_timer"] = None
                return False

	obj.color_set(alpha,alpha,alpha,alpha)
	return True

def resize_cb(ee):
    
    canvas = ee.evas
    bg = ee.data["bg"]
    bg.size = canvas.size
    w,h = bg.size
    rmap = ee.data["map"]
    rmap.size_set(w,w)
    rmap.pos_set(w,w)

    ee.data["line"].center = (w/2,h/2)

    return True
    
def delete_request_cb(ee):

    ecore.main_loop_quit()
    return True

def main():

	global ee
	w, h = SCREEN_GEOMETRY
	ee = ecore.evas.SoftwareX11(w=w, h=h)
	ee.title_set('diversity radar')
	ee.size_min_set(w,h)
	canvas = ee.evas

    # retrieve radar dbus 
	radar = radar_edbus.DBUS(r= 50.0)
	ee.data["radar"] = radar
	ee.data["speed"] = 0.9
	# create a dict to store all target information
	target_list = {}
	ee.data["target_list"] = target_list

	radar.viewport.connect_to_signal("ObjectAdded", ObjectAdded_cb,
    	dbus_interface="org.openmoko.Diversity.Viewport")
 	radar.viewport.connect_to_signal("ObjectRemoved", ObjectRemoved_cb,
 		dbus_interface="org.openmoko.Diversity.Viewport")
 	radar.startViewport()

 	bg = edje.Edje(ee.evas, file=THEME, group="panel")
 	bg.pos = (0, 0)
	bg.size = canvas.size
	bg.show()
 	bg.signal_callback_add("mouse,clicked,*", "*", button_cb)
 	ee.data["bg"] = bg

 	# get MAP canvas size (480,480) 
	rmap = radar_map.MAP(w,w,w,w)
	ee.data["map"] = rmap
	w,h = canvas.size

	# create a line object for animator line effect
	line = canvas.Line(color=(0, 255, 0, 255))
	w,h = canvas.size
	line.center = (w/2,w/2)
	line.data["degree"] = 0.0
	line.data["last_time"] = 0.0
	line.show()
	ee.data["line"] = line

 	ee.callback_resize = resize_cb
 	ee.callback_delete_request = delete_request_cb
 	ee.show()
 	ecore.animator_add(animate_line)
 	ecore.animator_frametime_set(1.0 / 30.0)
	ecore.main_loop_begin()
 	
if __name__ == "__main__":
	main()
